//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __EXCEPTION_H__
#define __EXCEPTION_H__

#include <linknode.h>
#include "ghost.h"

//#define _GHOSTTAG_DEBUG

typedef enum _LabelType {
    LabelType_Refer,
    LabelType_Host,
}LabelType;

class CGhostTag: public DLinkNode
{
public:
    void DoAtException();

public:
    CGhostTag(ProcessId processId,
           LabelType type,
           Ghost * pGhost)
          : m_processId(processId),
            m_labelType(type),
            m_pGhost(pGhost) {}
public:
    ProcessId m_processId;
    LabelType m_labelType;
    Ghost   * m_pGhost;

public:
    STATIC DLinkNode s_hashList[GHOST_HS_SLOTS];
    STATIC PVoid     s_hHashLock;

    STATIC ECode S_Initialize();
    STATIC void  S_Destroy();

#ifdef _GHOSTTAG_DEBUG
    STATIC void  S_Dump();
#else
    STATIC void  S_Dump() { return ;}
#endif

    STATIC ECode S_Create(
            /* [in] */ ProcessId processId,
            /* [in] */ LabelType labelType,
            /* [out] */ CGhostTag ** ppLabel); // just for req_start_process

    STATIC void S_Delete(
            /* [in] */ CGhostTag * pTag);   // just for req_start_process.

    STATIC void S_Attach(
            /* [in] */ CGhostTag * pTag,
            /* [in] */ Ghost * pGhost);     // just for req_start_process.

    STATIC ECode S_Create(
            /* [in] */ ProcessId processId,
            /* [in] */ LabelType labelType,
            /* [in] */ Ghost * pGhost);

    STATIC ECode S_Delete(
            /* [in] */ ProcessId processId,
            /* [in] */ Ghost * pGhost);

    STATIC ECode S_Delete(
            /* [in] */ ProcessId processId);
};

INLINE void CGhostTag::DoAtException()
{
    assert(NULL != m_pGhost);
    switch(m_labelType) {
    case LabelType_Refer:
        m_pGhost->Release();
        break;
    case LabelType_Host:
        m_pGhost->DoAtException();
        break;
    default:
        assert(0);
        break;
    }
    return ;
}

#endif //__EXCEPTION_H__

